/*
 * CCVisu is a tool for visual graph clustering
 * and general force-directed graph layout.
 * This file is part of CCVisu.
 *
 * Copyright (C) 2005-2011  Dirk Beyer
 *
 * CCVisu is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * CCVisu is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with CCVisu; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Please find the GNU Lesser General Public License in file
 * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
 *
 * Dirk Beyer    (firstname.lastname@uni-passau.de)
 * University of Passau, Bavaria, Germany
 */
package org.sosy_lab.util;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

/**
 * Colors for easy access by name.
 * Useful to write things like: Color myColor = Colors.get("blue");
 */
public enum Colors {

  // Main colors

  WHITE(255, 255, 255),

  LIGHTGRAY(192, 192, 192),

  GRAY(128, 128, 128),

  DARKGRAY(64, 64, 64),

  BLACK(0, 0, 0),

  RED(255, 0, 0),

  GREEN(0, 255, 0),

  BLUE(0, 0, 255),

  LIGHTRED(255, 128, 128),

  LIGHTGREEN(128, 255, 128),

  LIGHTBLUE(128, 128, 255),

  DARKRED(128, 0, 0),

  DARKGREEN(0, 128, 0),

  DARKBLUE(0, 0, 128),

  YELLOW(255, 255, 0),

  MAGENTA(255, 0, 255),

  CYAN(0, 255, 255),

  LIGHTYELLOW(255, 255, 192),

  LIGHTMAGENTA(255, 192, 255),

  LIGHTCYAN(192, 255, 255),

  DARKYELLOW(128, 128, 0),

  DARKMAGENTA(128, 0, 128),

  DARKCYAN(0, 128, 128),

  // Whites/Pastels

  SNOW(255, 250, 250),

  SNOW2(238, 233, 233),

  SNOW3(205, 201, 201),

  SNOW4(139, 137, 137),

  GHOSTWHITE(248, 248, 255),

  WHITESMOKE(245, 245, 245),

  GAINSBORO(220, 220, 220),

  FLORALWHITE(255, 250, 240),

  OLDLACE(253, 245, 230),

  LINEN(240, 240, 230),

  ANTIQUEWHITE(250, 235, 215),

  ANTIQUEWHITE2(238, 223, 204),

  ANTIQUEWHITE3(205, 192, 176),

  ANTIQUEWHITE4(139, 131, 120),

  PAPAYAWHIP(255, 239, 213),

  BLANCHEDALMOND(255, 235, 205),

  BISQUE(255, 228, 196),

  BISQUE2(238, 213, 183),

  BISQUE3(205, 183, 158),

  BISQUE4(139, 125, 107),

  PEACHPUFF(255, 218, 185),

  PEACHPUFF2(238, 203, 173),

  PEACHPUFF3(205, 175, 149),

  PEACHPUFF4(139, 119, 101),

  NAVAJOWHITE(255, 222, 173),

  MOCCASIN(255, 228, 181),

  CORNSILK(255, 248, 220),

  CORNSILK2(238, 232, 205),

  CORNSILK3(205, 200, 177),

  CORNSILK4(139, 136, 120),

  IVORY(255, 255, 240),

  IVORY2(238, 238, 224),

  IVORY3(205, 205, 193),

  IVORY4(139, 139, 131),

  LEMONCHIFFON(255, 250, 205),

  SEASHELL(255, 245, 238),

  SEASHELL2(238, 229, 222),

  SEASHELL3(205, 197, 191),

  SEASHELL4(139, 134, 130),

  HONEYDEW(240, 255, 240),

  HONEYDEW2(244, 238, 224),

  HONEYDEW3(193, 205, 193),

  HONEYDEW4(131, 139, 131),

  MINTCREAM(245, 255, 250),

  AZURE(240, 255, 255),

  ALICEBLUE(240, 248, 255),

  LAVENDER(230, 230, 250),

  LAVENDERBLUSH(255, 240, 245),

  MISTYROSE(255, 228, 225),

  // Grays

  DARKSLATEGRAY(49, 79, 79),

  DIMGRAY(105, 105, 105),

  SLATEGRAY(112, 138, 144),

  LIGHTSLATEGRAY(119, 136, 153),

  LIGHTGRAY2(211, 211, 211),

  // Blues

  MIDNIGHTBLUE(25, 25, 112),

  NAVY(0, 0, 128),

  CORNFLOWERBLUE(100, 149, 237),

  DARKSLATEBLUE(72, 61, 139),

  SLATEBLUE(106, 90, 205),

  MEDIUMSLATEBLUE(123, 104, 238),

  LIGHTSLATEBLUE(132, 112, 255),

  MEDIUMBLUE(0, 0, 205),

  ROYALBLUE(65, 105, 225),

  DODGERBLUE(30, 144, 255),

  DEEPSKYBLUE(0, 191, 255),

  SKYBLUE(135, 206, 250),

  LIGHTSKYBLUE(135, 206, 250),

  STEELBLUE(70, 130, 180),

  LIGHTSTEELBLUE(176, 196, 222),

  LIGHTBLUE2(173, 216, 230),

  POWDERBLUE(176, 224, 230),

  PALETURQUOISE(175, 238, 238),

  DARKTURQUOISE(0, 206, 209),

  MEDIUMTURQUOISE(72, 209, 204),

  TURQUOISE(64, 224, 208),

  LIGHTCYAN2(224, 255, 255),

  CADETBLUE(95, 158, 160),

  // Greens

  MEDIUMAQUAMARINE(102, 205, 170),

  AQUAMARINE(127, 255, 212),

  DARKGREEN2(0, 100, 0),

  DARKOLIVEGREEN(85, 107, 47),

  DARKSEAGREEN(143, 188, 143),

  SEAGREEN(46, 139, 87),

  MEDIUMSEAGREEN(60, 179, 113),

  LIGHTSEAGREEN(32, 178, 170),

  PALEGREEN(152, 251, 152),

  SPRINGGREEN(0, 255, 127),

  LAWNGREEN(124, 252, 0),

  CHARTREUSE(127, 255, 0),

  MEDIUMSPRINGGREEN(0, 250, 154),

  GREENYELLOW(173, 255, 47),

  LIMEGREEN(50, 205, 50),

  YELLOWGREEN(154, 205, 50),

  FORESTGREEN(34, 139, 34),

  OLIVEDRAB(107, 142, 35),

  DARKKHAKI(189, 183, 107),

  KHAKI(240, 230, 140),

  // Yellows

  PALEGOLDENROD(238, 232, 170),

  LIGHTGOLDENRODYELLOW(250, 250, 210),

  LIGHTYELLOW2(255, 255, 224),

  GOLD(255, 215, 0),

  LIGHTGOLDENROD(238, 221, 130),

  GOLDENROD(218, 165, 32),

  DARKGOLDENROD(184, 134, 11),

  // Browns

  ROSYBROWN(188, 143, 143),

  INDIANRED(205, 92, 92),

  SADDLEBROWN(139, 69, 19),

  SIENNA(160, 82, 45),

  PERU(205, 133, 63),

  BURLYWOOD(222, 184, 135),

  BEIGE(245, 245, 220),

  WHEAT(245, 222, 179),

  SANDYBROWN(244, 164, 96),

  TAN(210, 180, 140),

  CHOCOLATE(210, 105, 30),

  FIREBRICK(178, 34, 34),

  BROWN(165, 42, 42),

  // Oranges

  DARKSALMON(233, 150, 122),

  SALMON(250, 128, 114),

  LIGHTSALMON(255, 160, 122),

  ORANGE(255, 165, 0),

  DARKORANGE(255, 140, 0),

  CORAL(255, 127, 80),

  LIGHTCORAL(240, 128, 128),

  TOMATO(255, 99, 71),

  ORANGERED(255, 69, 0),

  // Pinks/Violets

  HOTPINK(255, 105, 180),

  DEEPPINK(255, 20, 147),

  PINK(255, 192, 203),

  LIGHTPINK(255, 182, 193),

  PALEVIOLETRED(219, 112, 147),

  MAROON(176, 48, 96),

  MEDIUMVIOLETRED(199, 21, 133),

  VIOLETRED(208, 32, 144),

  VIOLET(238, 130, 238),

  PLUM(221, 160, 221),

  ORCHID(218, 112, 214),

  MEDIUMORCHID(186, 85, 211),

  DARKORCHID(153, 50, 204),

  DARKVIOLET(148, 0, 211),

  BLUEVIOLET(138, 43, 226),

  PURPLE(160, 32, 240),

  MEDIUMPURPLE(147, 112, 219),

  THISTLE(216, 191, 216),

  // Other Mixtures
  PINK2(255, 175, 175),

  ORANGE2(255, 200, 0),

  CHOCOLATE2(139, 69, 19),

  DARKOLIVEGREEN2(110, 139, 61);

  /** The color of this enum object. */
  private final Color    color;

  /**
   * If a color is not yet declared for a name,
   * print out all available colors.
   * Set to false if this is not wanted.
   */
  private static boolean verbose = true;

  /**
   * Constructor.
   *
   * @param red   the red component of the color to create
   * @param green the green component of the color to create
   * @param blue  the blue component of the color to create
   */
  private Colors(int red, int green, int blue) {
    color = new Color(red, green, blue);
  }

  /**
   * Returns the Color object.
   * @return        Color object.
   */
  public Color get() {
    return color;
  }

  /**
   * Returns the Color object for a given name.
   * @param nameOfColor  String that represents a color name.
   * @return             Color object if it exists, null otherwise.
   */
  public static Colors valueOfUpper(String nameOfColor) {
    try {
      return Colors.valueOf(nameOfColor.toUpperCase());
    } catch (Exception e) {
      if (Colors.verbose) {
        System.err.println("Runtime error: Color '" + nameOfColor
            + "' unknown.");
        System.err.print("Available colors are: ");
        for (Colors colors : Colors.values()) {
          System.err.print(colors.toString() + ' ');
        }
        System.err.println();
      }
      return null;
    }
  }

  /**
   * Returns the Color object for a given name.
   * @param nameOfColor  String that represents a color name.
   * @return             Color object if it exists, null otherwise.
   */
  public static Color get(String nameOfColor) {
    Colors colors = Colors.valueOfUpper(nameOfColor);
    if (colors != null) {
      return colors.get();
    }

    // there is no color with this name
    return null;
  }

  /**
   * Returns the name of a given Color object.
   * @param color        Color object for which to find the name.
   * @return             String with name if color exists, null otherwise.
   */
  public static String toString(Color color) {
    for (Colors colors : Colors.values()) {
      if (colors.get().getRGB() == color.getRGB()) {
        return colors.toString();
      }
    }

    // we do not know the name for that color
    return null;
  }

  /**
   * Returns a list of distinct colors.
   * @param numOfColors  Number of colors to return.
   */
  public static List<Color> getMaxDistanceColors(int numOfColors) {
    List<Color> colors = new ArrayList<Color>(numOfColors);

    for (int i = 0; i < numOfColors; i++) {
      colors.add(Color.getHSBColor((float) i / numOfColors, 1, 1));
    }

    return colors;
  }

  @Override
  public String toString() {
    return name();
  }
}
